class Input:
    def __init__(self, name: str, type: str, value: str):
        self.name = name
        self.type = type
        self.value = value

    def to_dict(self):
        return {"name": self.name, "type": self.type, "value": self.value}

    def from_dict(dicto: dict) -> "Input":
        return Input(dicto["name"], dicto["type"], dicto.get("value", None))


class Output:
    def __init__(self, name: str, type: str, value: str):
        self.name = name
        self.type = type
        self.value = value

    def to_dict(self):
        return {"name": self.name, "type": self.type, "value": self.value}

    def from_dict(dicto: dict) -> "Output":
        return Output(dicto["name"], dicto["type"], dicto.get("value", None))


class Link:
    def __init__(
        self,
        origin_node_id: int,
        origin_slot: int,
        target_node_id: int,
        target_slot: int,
        type: str,
    ):
        self.origin_node_id = origin_node_id
        self.origin_slot = origin_slot
        self.target_node_id = target_node_id
        self.target_slot = target_slot
        self.type = type


class Node:
    def __init__(
        self,
        id: int,
        node_id: int,
        type: str,
        inputs: list[Input],
        outputs: list[Output],
        widgetValues: list,
        properties={},
    ):
        self.id = id
        self.node_id = node_id
        self.type = type
        self.inputs = inputs
        self.outputs = outputs
        self.widgetValues = widgetValues
        self.properties = properties

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "node_id": self.node_id,
            "type": self.type,
            "inputs": [input_item.to_dict() for input_item in self.inputs],
            "outputs": [output_item.to_dict() for output_item in self.outputs],
            "widgetValues": self.widgetValues,
            "properties": self.properties,
        }

    def from_dict(id: int, dicto: dict) -> "Node":
        return Node(
            id,
            int(dicto["id"]),
            dicto["type"],
            [Input.from_dict(d) for d in dicto.get("inputs", [])],
            [Output.from_dict(d) for d in dicto.get("outputs", [])],
            dicto.get("widgets_values", []),
            dicto["properties"],
        )
